package controller

import (
	"bluebell_qimi/dao/mysql"
	"bluebell_qimi/logic"
	"bluebell_qimi/models"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
)

// 处理注册请求的函数
func SignUpHandler(c *gin.Context) {
	//1. 获取参数和参数校验
	p := new(models.ParamSignUp)
	if err := c.ShouldBindJSON(p); err != nil {
		//请求参数有误，直接返回响应
		zap.L().Error("SignUp with invalid param", zap.Error(err))
		//判读err是不是
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans))) //把错误翻译
		return
	}

	//ShouldBindJSON只能判断字段类型，格式对不对，不能判断内容
	//手动地对请求参数进行详细地业务规则参数校验,结构体没有binding:"required eqfield=Password"等tag标签，如果有binding的tag标签，则下面不需要写
	//if len(p.Username) == 0 || len(p.Password) == 0 || len(p.RePassword) == 0 || p.Password != p.RePassword {
	//	zap.L().Error("SignUp with invalid param")
	//	//请求参数有误，直接返回响应
	//	c.JSON(http.StatusOK, gin.H{
	//		"msg": "请求参数有误！",
	//	})
	//	return
	//}

	//2. 业务处理
	if err := logic.SignUp(p); err != nil {
		zap.L().Error(" logic.SignUp failed ", zap.Error(err))
		if errors.Is(err, mysql.ErrorUserExist) {
			ResponseError(c, CodeUserExist)
		}
		ResponseError(c, CodeServerBusy)
		return
	}
	//3. 返回响应
	ResponseSuccess(c, nil)
}

func LoginHandler(c *gin.Context) {
	//1. 获取参数及参数校验
	p := new(models.ParamLogin)
	if err := c.ShouldBindJSON(p); err != nil {
		//请求参数有误，直接返回响应
		zap.L().Error("Login with invalid param", zap.Error(err))
		//判读err是不是
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans))) //把错误翻译
		return
	}
	//2. 业务逻辑处理
	user, err := logic.Login(p)
	if err != nil {
		//登录失败
		zap.L().Error("logic.Login(p) failed", zap.String("username", p.Username), zap.Error(err))
		if errors.Is(err, mysql.ErrorUserNotExist) {
			//用户名不存在
			ResponseError(c, CodeUserNotExist)
			return
		}
		//密码不正确
		ResponseError(c, CodeInvalidPassword)
		return
	}

	//3. 返回响应
	ResponseSuccess(c, gin.H{
		"user_id":   fmt.Sprintf("%d", user.UserID), //如果id值大于2^53-1，前端接不到，因为前端js的数字int64类型最大值是2^53-1（±），而后端是2^63-1（±），防止前后端token失效
		"user_name": user.Username,
		"token":     user.Token,
	})
}

// 老版 token为int
/*func LoginHandler(c *gin.Context) {
	//1. 获取参数及参数校验
	p := new(models.ParamLogin)
	if err := c.ShouldBindJSON(p); err != nil {
		//请求参数有误，直接返回响应
		zap.L().Error("Login with invalid param", zap.Error(err))
		//判读err是不是
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans))) //把错误翻译
		return
	}
	//2. 业务逻辑处理
	token, err := logic.Login(p)
	if err != nil {
		//登录失败
		zap.L().Error("logic.Login(p) failed", zap.String("username", p.Username), zap.Error(err))
		if errors.Is(err, mysql.ErrorUserNotExist) {
			ResponseError(c, CodeUserNotExist)
			return
		}
		ResponseError(c, CodeInvalidPassword)
		return
	}

	//3. 返回响应
	ResponseSuccess(c, token)
}*/
